﻿using LitJson;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Assets.MatchVS {
    public class Http {

        public static String UrlOpenHostTest = "http://testopen.matchvs.com";
        public static String UrlOpenHost = "http://open.matchvs.com";
        public static String UrlPayHostTest = "http://testpay.matchvs.com";
        public static String UrlPayHost = "http://pay.matchvs.com";
        public static String UrlUserHostTest = "http://testuser.matchvs.com";
        public static String UrlUserHost = "http://user.matchvs.com";

        public static String UrlGetUserRank = "/wc4/getUserRank.do?userID={0:D}&gameID={1:D}&token={2}&item={3}";
        public static String UrlAward = "/wc4/award.do?awardID={0:D}&gameID={1:D}&userID={2:D}&sign={3}";
        public static String UrlAwardInfo = "/wc4/awardInfo.do?awardID={0:D}&gameID={1:D}&userID={2:D}&sign={3}";
        public static String UrlAwardRec = "/wc4/awardRec.do?awardID={0:D}&gameID={1:D}&userID={2:D}&sign={3}";
        public static String UrlSafeExchange = "/wc4/safeExchange.do?data={0}&gameID={1:D}&userID={2:D}&sign={3}";

        public static String UrlBattleFields = "/wc3/getBattleFields.do?gameID={0:D}&versionID={1:D}";
        public static String UrlSignSubsidy = "/wc4/signSubsidy.do?gameID={0:D}&userID={1:D}&sign={2}";
        public static String UrlBrokeSubsidy = "/wc4/brokeSubsidy.do?gameID={0:D}&userID={1:D}&productID={2:D}";
        public static String UrlSafeSpend = "/wc4/safeSpend.do?data={0}&gameID={1:D}&userID={2:D}&sign={3}";
        public static String UrlHashGet = "/wc5/hashGet.do?gameID={0:D}&key={1:D}&userID={2:D}&sign={3}";
        public static String UrlHashSet = "/wc5/hashSet.do?gameID={0:D}&key={1:D}&userID={2:D}&value={3}&sign={4:D}";
        public static String UrlGetSystemTime = "/wc4/GetSystemTime.do";
        public static String UrlGetItemRank = "/wc4/getItemRank.do?gameID={0:D}&item={1}&top={2:D}";
        public static String UrlOfflineSyncProduct = "/wc4/offlineSyncProduct.do?count={0:D}&gameID={1:D}&productID={2:D}&userID={3:D}&sign={4}";
        public static String UrlGetUserBattleInfo = "/wc5/getUserBattleInfo.do?userID={0:d}&gameID={1:d}&sign={2}";
        public static String UrlGetUserInfoList = "/wc3/getUserInfoX.do?userIDList=";
        public static String UrlGetRoundResult = "/rocket/wc6/getRoundResult?gameID={0:D}&roundID={1:D}&userID={2:D}&sign={3}";



        /** @brief 商品信息 */
        public class Product {
			/** @brief 游戏ID **/
            public int gameID;
			/** @brief 商品ID **/
            public int productID;
			/** @brief 商品类型 **/
            public int type;   
			/** @brief 存货数量 **/
            public int count;  
			/** @brief 数量count的小数部分 **/
            public int countDecimal;   
			/** @brief 钻分 **/
            public int diamondCent;    
        }
		
        public delegate void OnRsp(String context, String err);
        private static int environment = 0;
        /// <summary>
        /// 得到运行环境 0为正式环境 1为测试环境
        /// </summary>
        public static int getEnvironment() {
            return environment;
        }
        /// <summary>
        /// 设置运行环境为测试或者正式,0为正式环境 1为测试环境
        /// </summary>
        /// <param name="env"> 0为正式环境 1为测试环境</param>
        public static void setEnvironment(int env) {
            environment = env ;
        }
        /** @brief 根据环境得到Open服务器的域名 */
        public static String HttpGetOpenServer() {

            int nRunMode = getEnvironment();
            switch(nRunMode) {
                case 1:
                    return UrlOpenHostTest;
                default:
                    return UrlOpenHost;
            }
        }
        /** @brief 根据环境得到Pay服务器的域名 */
        public static String HttpGetPayServer() {

            int nRunMode = getEnvironment();
            switch(nRunMode) {
                case 1:
                    return UrlPayHostTest;
                default:
                    return UrlPayHost;
            }
        }
		/** @brief 根据环境得到User服务器的域名 */
        public static String HttpGetUserServer() {

            int nRunMode = getEnvironment();
            switch(nRunMode) {
                case 1:
                    return UrlUserHostTest;
                default:
                    return UrlUserHost;
            }
        }
		/**
		* @brief 返回http IEnumerator
		* @param url 链接
		* @param cb 异步回调函数
		* @return 
		*/
        static IEnumerator getHttp(String url, String pars, OnRsp cb) {
            WWW www = new WWW(url + pars);

            yield return www;
            log("www on request ->" + url);
            if(!IsEmpty(www.error)) {
                cb("", www.error);
                loge("www on response->" + " err:" + www.error);
            }
            if(www.isDone) {
                cb(www.text, "");
                log("www on response->" + www.text);
            }
        }
		/**
		* @brief 调用cocos http库的异步做http请求
		* @param context 上下文
		* @param url 链接
		* @param pars 参数
		* @param cb 异步回调函数
		* @return 
		*/
        static void doGet(MonoBehaviour context, String url, String pars, OnRsp cb) {
            context.StartCoroutine(getHttp(url, pars, cb));
        }

        private static bool IsEmpty(string error) {
            return error == null || error.Length <= 0;
        }

        public static string Md5(string input) {
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes); StringBuilder sb = new StringBuilder();
            for(int i = 0; i < hash.Length; i++) { sb.Append(hash[i].ToString("X2")); }
            return sb.ToString().ToLower();
        }
        private static void log(string v, System.Object strUrl) {
            log(v + strUrl);
        }
        private static void log(string v) {
            Debug.Log(v);
        }
        private static void loge(string v) {
            Debug.LogError(v);
        }
		/**
		* @brief  奖励
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param awardID 奖励的ID 
		* @return 
		*/  
        public static void award(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID, int awardID) {


            String signString = String.Format("{0}&awardID={1:D}&gameID={2:D}&userID={3:D}&{4}", appkey, awardID, gameID, userID, token);

            String toMd5 = Md5(signString);


            String strUrl = "";
            strUrl += HttpGetPayServer();
            strUrl += UrlAward;



            strUrl = String.Format(strUrl, awardID, gameID, userID, toMd5);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief 我的奖励情况
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param awardID 奖励的ID 
		* @return 
		*/  
        public static void awardInfo(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID, int awardID) {
            String signString = String.Format("{0}&awardID={1:D}&gameID={2:D}&userID={3:D}&{4}", appkey, awardID, gameID, userID, token);
            String toMd5 = Md5(signString);
            String strUrl = "";
            strUrl += HttpGetPayServer();
            strUrl += UrlAwardInfo;
            strUrl = String.Format(strUrl, awardID, gameID, userID, toMd5);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief 我的奖励情况
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param awardID 奖励的ID 
		* @return 
		*/  
        public static void awardRec(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID, int awardID) {
            String signString = String.Format("{0}&awardID={1:D}&gameID={2:D}&userID={3:D}&{4}", appkey, awardID, gameID, userID, token);
            String toMd5 = Md5(signString);
            String strUrl = "";
            strUrl += HttpGetPayServer();
            strUrl += UrlAwardRec;
            strUrl = String.Format(strUrl, awardID, gameID, userID, toMd5);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief  商品兑换
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param srcArray 兑换的源商品数组
		* @param srcLen   兑换的源商品数组个数
		* @param dstArray 兑换的目标商品数组
		* @param dstLen   兑换的目标商品数组个数
		* @return 
		*/
        public static void safeExchange(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID, Product[] srcArray, int srcLen, Product[] dstArray, int dstLen) {

            if(srcArray == null || srcLen == 0 || dstArray == null || dstLen == 0 || srcLen > 128 || dstLen > 128) {
                log("srcArray==null||srcLen==0||dstArray==null||dstLen==0||srcLen>128||dstLen>128");
                return;
            }
            int[] a = new int[srcLen + dstLen]; int i = 0;
            for(i = 0; i < srcLen; i++) {
                a[i] = srcArray[i].productID;
            }
            for(i = 0; i < dstLen; i++) {
                a[i + srcLen] = dstArray[i].productID;
            }
            Array.Sort<int>(a);

            String buf = "";


            String data = "";
            data = data + appkey;
            for(int j = 0; j < srcLen + dstLen; j++) {
                int id = a[j];
                log("%d", id);
                for(i = 0; i < srcLen; i++) {
                    if(id == srcArray[i].productID) {
                        String temp = String.Format("&{0:D}={1:f}", srcArray[i].productID, (srcArray[i].count + srcArray[i].countDecimal * 0.01f));
                        data += temp;

                        break;
                    }
                }
                for(i = 0; i < dstLen; i++) {
                    if(id == dstArray[i].productID) {
                        String temp = String.Format("&{0:D}={1:f}", dstArray[i].productID, (dstArray[i].count + dstArray[i].countDecimal * 0.01f));
                        data += temp;

                        break;
                    }
                }
            }

            String md5String = String.Format("{0}&gameID={1:d}&userID={2:d}&{3}", data, gameID, userID, token);
            log("sign context :%s", buf);



            String toMd5 = Md5(md5String);
            JsonWriter jo1 = new JsonWriter();
            jo1.WriteObjectStart();
            jo1.WritePropertyName("productSrc");
            jo1.WriteArrayStart();
            for(i = 0; i < srcLen; i++) {
                JsonWriter joitem = new JsonWriter();
                joitem.WriteObjectStart();
                joitem.WritePropertyName("productID");
                joitem.Write(srcArray[i].productID);
                joitem.WritePropertyName("countDecimal");
                joitem.Write(srcArray[i].countDecimal);
                joitem.WritePropertyName("count");
                joitem.Write(srcArray[i].count);
                joitem.WriteObjectEnd();
                jo1.Write(joitem.ToString());

            }
            jo1.WriteArrayEnd();

            jo1.WritePropertyName("productDes");
            jo1.WriteArrayStart();
            for(i = 0; i < dstLen; i++) {
                JsonWriter joitem = new JsonWriter();
                joitem.WriteObjectStart();
                joitem.WritePropertyName("productID");
                joitem.Write(dstArray[i].productID);
                joitem.WritePropertyName("countDecimal");
                joitem.Write(dstArray[i].countDecimal);
                joitem.WritePropertyName("count");
                joitem.Write(dstArray[i].count);
                joitem.WriteObjectEnd();

                jo1.Write(joitem.ToString());
            }
            jo1.WriteArrayEnd();
            jo1.WriteObjectEnd();

            String dataJSON = jo1.ToString();

            String strUrl = "";
            strUrl += HttpGetPayServer();
            strUrl += UrlSafeExchange;
            strUrl = String.Format(strUrl, dataJSON, gameID, userID, toMd5);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		
		/**
		* @brief  商品消费
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param srcArray 兑换的源商品数组
		* @param srcLen   兑换的源商品数组个数
		* @return 
		*/
        public static void safeSpend(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID, Product[] srcArray, int srcLen) {

            if(srcArray == null || srcLen == 0 || srcLen > 128) {
                log("srcArray==null||srcLen==0||dstArray==null||dstLen==0||srcLen>128||dstLen>128");
                return;
            }
            int[] a = new int[srcLen]; int i = 0;
            for(i = 0; i < srcLen; i++) {
                a[i] = srcArray[i].productID;
            }

            Array.Sort<int>(a);

            String buf = "";


            String data = "";
            data = data + appkey;
            for(int j = 0; j < srcLen; j++) {
                int id = a[j];
                log("%d", id);
                for(i = 0; i < srcLen; i++) {
                    if(id == srcArray[i].productID) {
                        String temp = String.Format("&{0:D}={1:f}", srcArray[i].productID, (srcArray[i].count + srcArray[i].countDecimal * 0.01f));
                        data += temp;

                        break;
                    }
                }

            }

            String md5String = String.Format("{0}&gameID={1:d}&userID={2:d}&{3}", data, gameID, userID, token);
            log("sign context :%s", buf);



            String toMd5 = Md5(md5String);
            JsonWriter jo1 = new JsonWriter();
            jo1.WriteObjectStart();
            jo1.WritePropertyName("products");
            jo1.WriteArrayStart();
            for(i = 0; i < srcLen; i++) {
                JsonWriter joitem = new JsonWriter();
                joitem.WriteObjectStart();
                joitem.WritePropertyName("productID");
                joitem.Write(srcArray[i].productID);
                joitem.WritePropertyName("countDecimal");
                joitem.Write(srcArray[i].countDecimal);
                joitem.WritePropertyName("count");
                joitem.Write(srcArray[i].count);
                joitem.WriteObjectEnd();
                jo1.Write(joitem.ToString());

            }
            jo1.WriteArrayEnd();

            jo1.WriteObjectEnd();

            String dataJSON = jo1.ToString().Replace("\\\"", "\"").Replace("[\"", "[").Replace("\"]", "]").Replace("}\"", "}").Replace("\"{", "{");

            String strUrl = "";
            strUrl += HttpGetPayServer();
            strUrl += UrlSafeSpend;
            strUrl = String.Format(strUrl, dataJSON, gameID, userID, toMd5);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief 场次信息
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param gameID 游戏ID
		* @param versionID 版本ID
		* @return 
		*/   
        public static void battleFields(MonoBehaviour context, OnRsp callback, int gameID, int versionID) {



            String strUrl = "";
            strUrl += HttpGetOpenServer();
            strUrl += UrlBattleFields;
            strUrl = String.Format(strUrl, gameID, versionID);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief  登录奖励
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @return 
		*/	
        public static void loginSubsidy(MonoBehaviour context, OnRsp callback, String appkey, int gameID, int userID, String token) {



            String signString = String.Format("{0}&gameID={1:D}&userID={2:D}&{3}", appkey, gameID, userID, token);



            String toMd5 = Md5(signString);



            String strUrl = "";
            strUrl += HttpGetPayServer();
            strUrl += UrlSignSubsidy;
            strUrl = String.Format(strUrl, gameID, userID, toMd5);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief  破产补助
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param productID 商品ID
		* @return 
		*/  
        public static void brokeSubsidy(MonoBehaviour context, OnRsp callback, int gameID, int userID, int productID) {



            String strUrl = "";
            strUrl += HttpGetPayServer();
            strUrl += UrlBrokeSubsidy;
            strUrl = String.Format(strUrl, gameID, userID, productID);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief  服务端时间
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @return 
		*/
        public static void getSystemTime(MonoBehaviour context, OnRsp callback) {


            String strUrl = "";
            strUrl += HttpGetOpenServer();
            strUrl += UrlGetSystemTime;
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief  服务器存储设置
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param key    自定义存储字段编号
		* @param value  自定义存储字段的值
		* @return 
		*/
        public static void hashSet(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID, int key, String value) {


            String signString = String.Format("{0}&gameID={1:D}&key={2:D}&userID={3:D}&value={4}&{5}", appkey, gameID, key, userID, value, token);



            String toMd5 = Md5(signString);

            String strUrl = "";
            strUrl += HttpGetOpenServer();
            strUrl += UrlHashSet;
            strUrl = String.Format(strUrl, gameID, key, userID, value, toMd5);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief  服务器存储查询
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param key    自定义存储字段编号
		* @return 
		*/
        public static void hashGet(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID, int key) {


            String signString = String.Format("{0}&gameID={1:D}&key={2:D}&userID={3:D}&{4}", appkey, gameID, key, userID, token);




            String toMd5 = Md5(signString);



            String strUrl = "";
            strUrl += HttpGetOpenServer();
            strUrl += UrlHashGet;
            strUrl = String.Format(strUrl, gameID, key, userID, toMd5);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief  获取某一个字段的排名
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param userID 用户ID
		* @param token  用户token
		* @param gameID 游戏ID
		* @param item   查询的字段
		* @return 
		*/		
        public static void getUserRank(MonoBehaviour context, OnRsp callback, int gameID, String item, int userID, String token) {


            String strUrl = "";
            strUrl += HttpGetOpenServer();
            strUrl += UrlGetUserRank;

            strUrl = String.Format(strUrl, userID, gameID, token, item);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief  获取某一个字段的排名
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param gameID 游戏ID
		* @param item   查询的字段
		* @param top   排名个数.比如前20名
		* @return 
		*/
        public static void getItemRank(MonoBehaviour context, OnRsp callback, int gameID, String item, int top) {


            String strUrl = "";
            strUrl += HttpGetOpenServer();
            strUrl += UrlGetItemRank;
            strUrl = String.Format(strUrl, gameID, item, top);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }
		/**
		* @brief  金币首次线下同步
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param productID 商品的ID 
		* @param count   商品奖励的数量
		* @return 
		*/
        public static void offlineSyncProduct(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID, int productID, int count) {

            String signString = String.Format("{0}&count={1:D}&gameID={2:D}&productID={3:D}&userID={4:D}&{5}", appkey, count, gameID, productID, userID, token);
            String toMd5 = Md5(signString);
            String strUrl = "";
            strUrl += HttpGetPayServer();
            strUrl += UrlOfflineSyncProduct;
            strUrl = String.Format(strUrl, count, gameID, productID, userID, toMd5);
            // log("url:%s", strUrl);
            doGet(context, strUrl, "", callback);
        }

        public static void getUserBattleInfo(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID) {

            String signString = String.Format("{0}&gameID={1:d}&userID={2:d}&{3}", appkey, gameID, userID, token);
            String toMd5 = Md5(signString);
            String strUrl = "";
            strUrl += HttpGetOpenServer();
            strUrl += UrlGetUserBattleInfo;
            strUrl = String.Format(strUrl, userID, gameID,  toMd5);
            doGet(context, strUrl, "", callback);
        }

        /**
		* @brief 获取奖励信息
		* @param context Unity中的对象.
		* @param callback 用于接收返回数据的回调函数
		* @param appkey app的KEY,通过注册开发者创建游戏得到
		* @param token  用户token
		* @param userID 用户ID
		* @param gameID 游戏ID
		* @param productID 商品的ID 
		* @param count   商品奖励的数量
		* @return 
		*/
        public static void getRoundResult(MonoBehaviour context, OnRsp callback, String appkey, String token, int userID, int gameID,int roundID) {

            String signString = String.Format("{0}&gameID={1:D}&roundID={2:D}&userID={3:D}&{4}", appkey, gameID, roundID, userID, token);
            String toMd5 = Md5(signString);
            String strUrl = "";
            strUrl += HttpGetOpenServer();
            strUrl += UrlGetRoundResult;
            strUrl = String.Format(strUrl, gameID, roundID,userID, toMd5);
            doGet(context, strUrl, "", callback);
        }
       
        /**
        * @brief  批量获取用户信息
        * @param context cocos中的对象.
        * @param callback 用于接收返回数据的回调函数
        * @param userIDs 用户ID数组
        * @param userIDsLen 用户ID数组长度
        * @return 
        */
        public static void getUserInfoList(MonoBehaviour context, OnRsp callback, int[] userIDs) {
            String strUrl = "";
            strUrl += HttpGetUserServer();
            strUrl += UrlGetUserInfoList;
            for(int i = 0; i < userIDs.Length; i++) {
                if(i > 0) {
                    strUrl += ",";
                }
                strUrl += userIDs[i];
            }
            doGet(context, strUrl, "", callback);

        }

    }
   
}
